﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DAO
{
    public class DAOCD
    {
        public static List<Entidad.EntidadCD> getTodas()
        {
            List<Entidad.EntidadCD> lista = new List<Entidad.EntidadCD>();
            AccesoDato ad = new AccesoDato();
            try
            {
                String sql = "Select * from cd";
                SqlDataReader dr = ad.ejecutarSql(sql, null);

                while (dr.Read())
                {
                    Entidad.EntidadCD e = new Entidad.EntidadCD();
                    e.codigo_cd = int.Parse(dr["codigo_cd"].ToString());
                    e.fecha_ultima_reposicion = Convert.ToDateTime(dr["fecha_ultimo_reposicion"].ToString());
                    e.id_cd = int.Parse(dr["id_cd"].ToString());
                    e.id_genero = int.Parse(dr["id_genero"].ToString());
                    e.id_sello_discografico = int.Parse(dr["id_sello_discografico"].ToString());
                    e.precio_venta = float.Parse(dr["precio_venta"].ToString());
                    e.stock = int.Parse(dr["stock"].ToString());
                    e.titulo = dr["titulo"].ToString();
                    if (dr["fecha_publicacion"] != DBNull.Value)
                    {
                        e.fecha_publicacion = Convert.ToDateTime(dr["fecha_publicacion"].ToString());
                    }
                    lista.Add(e);
                }
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al obtener todos los cds");
            }
            finally
            {
                ad.cerrarDR();
            }

            return lista;
        }

        public static List<Entidad.EntidadCD> getCDsParaTransaccion()
        {
            List<Entidad.EntidadCD> lista = new List<Entidad.EntidadCD>();
            AccesoDato ad = new AccesoDato();
            try
            {
                String sql = "Select * from cd where stock <= 100";
                SqlDataReader dr = ad.ejecutarSql(sql, null);

                while (dr.Read())
                {
                    Entidad.EntidadCD e = new Entidad.EntidadCD();
                    e.codigo_cd = int.Parse(dr["codigo_cd"].ToString());
                    e.fecha_ultima_reposicion = Convert.ToDateTime(dr["fecha_ultimo_reposicion"].ToString());
                    e.id_cd = int.Parse(dr["id_cd"].ToString());
                    e.id_genero = int.Parse(dr["id_genero"].ToString());
                    e.id_sello_discografico = int.Parse(dr["id_sello_discografico"].ToString());
                    e.precio_venta = float.Parse(dr["precio_venta"].ToString());
                    e.stock = int.Parse(dr["stock"].ToString());
                    e.titulo = dr["titulo"].ToString();
                    if (dr["fecha_publicacion"] != DBNull.Value)
                    {
                        e.fecha_publicacion = Convert.ToDateTime(dr["fecha_publicacion"].ToString());
                    }
                    lista.Add(e);
                }
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al obtener todos los cds");
            }
            finally
            {
                ad.cerrarDR();
            }

            return lista;
        }

        public static void Eliminar(Entidad.EntidadCD cd)
        {
            String sql = "delete from cd where id_cd = @id_cd";
            AccesoDato ad = new AccesoDato();
            try
            {
                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("@id_cd", cd.id_cd));
                ad.ejecutarNonQuery(sql, p);
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al eliminar el cd");
            }
        }

        public static void Guardar(Entidad.EntidadCD cd)
        {
            String sql = @"insert into cd (codigo_cd,titulo,precio_venta,id_genero,fecha_publicacion,stock,fecha_ultimo_reposicion,id_sello_discografico)
                                    values(@codigo_cd,@titulo,@precio_venta,@id_genero,@fecha_publicacion,@stock,@fecha_ultimo_reposicion,@id_sello_discografico)";
            AccesoDato ad = new AccesoDato();
            try
            {
                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("@codigo_cd", cd.codigo_cd));
                p.Add(new SqlParameter("@fecha_ultimo_reposicion", cd.fecha_ultima_reposicion));
                p.Add(new SqlParameter("@id_genero", cd.id_genero));
                p.Add(new SqlParameter("@id_sello_discografico", cd.id_sello_discografico));
                p.Add(new SqlParameter("@precio_venta", cd.precio_venta));
                p.Add(new SqlParameter("@stock", cd.stock));
                p.Add(new SqlParameter("@titulo", cd.titulo));
                if (cd.fecha_publicacion.HasValue)
                {
                    p.Add(new SqlParameter("@fecha_publicacion", cd.fecha_publicacion));
                }
                else
                {
                    p.Add(new SqlParameter("@fecha_publicacion", DBNull.Value));
                }

                ad.ejecutarNonQuery(sql, p);
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al guardar el cd");
            }
        }

        public static Entidad.EntidadCD Buscar(int cdId)
        {

            Entidad.EntidadCD e = new Entidad.EntidadCD();
            AccesoDato ad = new AccesoDato();
            try
            {
                String sql = "Select * from cd where id_cd = @id_cd";
                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("id_cd", cdId));
                SqlDataReader dr = ad.ejecutarSql(sql, p);

                while (dr.Read())
                {
                    e.codigo_cd = int.Parse(dr["codigo_cd"].ToString());
                    e.fecha_ultima_reposicion = Convert.ToDateTime(dr["fecha_ultimo_reposicion"].ToString());
                    e.id_cd = int.Parse(dr["id_cd"].ToString());
                    e.id_genero = int.Parse(dr["id_genero"].ToString());
                    e.id_sello_discografico = int.Parse(dr["id_sello_discografico"].ToString());
                    e.precio_venta = float.Parse(dr["precio_venta"].ToString());
                    e.stock = int.Parse(dr["stock"].ToString());
                    e.titulo = dr["titulo"].ToString();
                    if (dr["fecha_publicacion"] != DBNull.Value)
                    {
                        e.fecha_publicacion = Convert.ToDateTime(dr["fecha_publicacion"].ToString());
                    }
                }
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al obtener el cd");
            }
            finally
            {
                ad.cerrarDR();
            }

            return e;
        }

        public static void Actualizar(Entidad.EntidadCD cd)
        {
            String sql = @"update cd set codigo_cd=@codigo_cd,
                        titulo=@titulo,
                        precio_venta=@precio_venta,
                        id_genero=@id_genero,
                        fecha_publicacion=@fecha_publicacion,
                        stock=@stock,
                        fecha_ultimo_reposicion=@fecha_ultimo_reposicion,
                        id_sello_discografico=@id_sello_discografico 
                        where id_cd = @id_cd";

            AccesoDato ad = new AccesoDato();
            try
            {
                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("@codigo_cd", cd.codigo_cd));
                p.Add(new SqlParameter("@id_cd", cd.id_cd));
                p.Add(new SqlParameter("@fecha_ultimo_reposicion", cd.fecha_ultima_reposicion));
                p.Add(new SqlParameter("@id_genero", cd.id_genero));
                p.Add(new SqlParameter("@id_sello_discografico", cd.id_sello_discografico));
                p.Add(new SqlParameter("@precio_venta", cd.precio_venta));
                p.Add(new SqlParameter("@stock", cd.stock));
                p.Add(new SqlParameter("@titulo", cd.titulo));
                if (cd.fecha_publicacion.HasValue)
                {
                    p.Add(new SqlParameter("@fecha_publicacion", cd.fecha_publicacion));
                }
                else
                {
                    p.Add(new SqlParameter("@fecha_publicacion", DBNull.Value));
                }

                ad.ejecutarNonQuery(sql, p);
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al actualizar el cd");
            }
        }
        static public List<Entidad.CDQueryInforme> buscarFiltro(DateTime? fechaDesde, DateTime? fechaHasta, int? id_genero, int? id_sello_discografico, string ordenarPor="titulo")
        {
            List<Entidad.CDQueryInforme> lista = new List<Entidad.CDQueryInforme>();
            List<SqlParameter> p = new List<SqlParameter>();
            AccesoDato ac = null;
            try
            {
                ac = new AccesoDato();
                string sql = @"select cd.id_cd, cd.titulo, sello_discografico.nombre as sello_discografico_nombre, genero.nombre as genero_nombre, sum(detalle_factura.cantidad) as cantidad_vendida, 
                sum(detalle_factura.cantidad * detalle_factura.precio) as ganancia
                from cd
                inner join genero on genero.id_genero = cd.id_genero
                inner join sello_discografico on sello_discografico.id_sello_discografico = cd.id_sello_discografico
                inner join detalle_factura on detalle_factura.id_cd = cd.id_cd
                inner join factura on factura.id_factura = detalle_factura.id_factura
                where 1=1";

                if (fechaDesde.HasValue)
                {
                    sql += " and factura.fecha >= @fechaDesde";
                    p.Add(new SqlParameter("@fechaDesde", fechaDesde));
                }
                if (fechaHasta.HasValue)
                {
                    sql += " and factura.fecha <= @fechaHasta";
                    p.Add(new SqlParameter("@fechaHasta", fechaHasta));
                }
                if (id_genero.HasValue)
                {
                    sql += " and cd.id_genero = @id_genero";
                    p.Add(new SqlParameter("@id_genero", id_genero));
                }
                if (id_sello_discografico.HasValue)
                {
                    sql += " and cd.id_sello_discografico = @id_sello_discografico";
                    p.Add(new SqlParameter("@id_sello_discografico", id_sello_discografico));
                }
                sql += " group by cd.id_cd, cd.titulo, sello_discografico.nombre, genero.nombre";
                sql += " order by " + ordenarPor;
                SqlDataReader dr = ac.ejecutarSql(sql, p);
                while (dr.Read())
                {
                    Entidad.CDQueryInforme cd = new Entidad.CDQueryInforme();
                    cd.id_cd = int.Parse(dr["id_cd"].ToString());
                    cd.cantidad_vendida = int.Parse(dr["cantidad_vendida"].ToString());
                    cd.ganancia = float.Parse(dr["ganancia"].ToString());
                    cd.titulo = dr["titulo"].ToString();
                    cd.nombre_genero = dr["genero_nombre"].ToString();
                    cd.nombre_sello_discografico = dr["sello_discografico_nombre"].ToString();
                    lista.Add(cd);
                }
            }
            catch (ApplicationException)
            {

                throw new ApplicationException("Error al buscar cds");
            }
            finally
            {
                ac.cerrarDR();
            }
            return lista;
        }

        public static Boolean codigoCdEnUso(int codigo_cd)
        {
            Boolean uso = false;
            AccesoDato ad = new AccesoDato();
            try
            {
                String sql = "Select * from cd where codigo_cd = @codigo_cd";
                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("codigo_cd", codigo_cd));
                SqlDataReader dr = ad.ejecutarSql(sql, p);

                while (dr.Read())
                {
                    uso = true;
                }
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al obtener el cd");
            }
            finally
            {
                ad.cerrarDR();
            }

            return uso;
        }

        public static List<Entidad.EntidadCD> BuscarPorTitulo(string titulo)
        {
            List<Entidad.EntidadCD> lista = new List<Entidad.EntidadCD>();
            AccesoDato ad = new AccesoDato();
            try
            {
                String sql = "Select * from cd where titulo like @titulo";
                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("@titulo", titulo + "%"));
                SqlDataReader dr = ad.ejecutarSql(sql, p);

                while (dr.Read())
                {
                    Entidad.EntidadCD e = new Entidad.EntidadCD();
                    e.id_cd = int.Parse(dr["id_cd"].ToString());
                    e.codigo_cd = int.Parse(dr["codigo_cd"].ToString());
                    e.fecha_ultima_reposicion = Convert.ToDateTime(dr["fecha_ultimo_reposicion"].ToString());
                    e.id_genero = int.Parse(dr["id_genero"].ToString());
                    e.id_sello_discografico = int.Parse(dr["id_sello_discografico"].ToString());
                    e.precio_venta = float.Parse(dr["precio_venta"].ToString());
                    e.stock = int.Parse(dr["stock"].ToString());
                    e.titulo = dr["titulo"].ToString();
                    if (dr["fecha_publicacion"] != DBNull.Value)
                    {
                        e.fecha_publicacion = Convert.ToDateTime(dr["fecha_publicacion"].ToString());
                    }
                    lista.Add(e);
                }
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al obtener todos los cds");
            }
            finally
            {
                ad.cerrarDR();
            }

            return lista;
        }

        public static List<Entidad.EntidadCD> getTodasGrillaVenta()
        {
            List<Entidad.EntidadCD> lista = new List<Entidad.EntidadCD>();
            AccesoDato ad = new AccesoDato();
            try
            {
                String sql = "Select id_cd, codigo_cd, titulo, fecha_ultimo_reposicion, stock from cd where stock > 0 order by titulo";
                SqlDataReader dr = ad.ejecutarSql(sql, null);

                while (dr.Read())
                {
                    Entidad.EntidadCD e = new Entidad.EntidadCD();
                    e.codigo_cd = int.Parse(dr["codigo_cd"].ToString());
                    e.fecha_ultima_reposicion = Convert.ToDateTime(dr["fecha_ultimo_reposicion"].ToString());
                    e.id_cd = int.Parse(dr["id_cd"].ToString());
                    e.stock = int.Parse(dr["stock"].ToString());
                    e.titulo = dr["titulo"].ToString();              
                    lista.Add(e);
                }
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al obtener todos los cds");
            }
            finally
            {
                ad.cerrarDR();
            }

            return lista;
        }
    }

}
